// 工具模块--监听路由变化--值得学习

/**
 * 监听路由变化
 * 1.mitt：发布订阅模式器依赖
 * 2.单独监听路由会浪费渲染性能。使用发布订阅模式去进行分发管理。
 * 3.用mitt替换了vue-router本身的路由守卫渲染, 优化性能
 */
import mitt, { Handler } from 'mitt';
import type { RouteLocationNormalized } from 'vue-router';

// 实例化发布订阅模块
const emitter = mitt();

// 定义发布订阅路由key
const key = Symbol('ROUTE_CHANGE');

// 记录最后监听到的路由记录
let latestRoute: RouteLocationNormalized;

// 设置路由发布(设置监听)
export function setRouteEmitter(to: RouteLocationNormalized) {
  // 发送数据
  emitter.emit(key, to);
  latestRoute = to;
}

// 设置路由订阅(监听数据)
export function listenerRouteChange(
  handler: (route: RouteLocationNormalized) => void,
  immediate = true
) {
  // 监听数据
  emitter.on(key, handler as Handler);
  // 初始化第一次条件：有路由数据
  if (immediate && latestRoute) {
    handler(latestRoute);
  }
}

// 清空路由发布
export function removeRouteListener() {
  emitter.off(key);
}
